package com.zz.concurrent.base;

/**
 * Author: zhangzhen
 * DATE: Created in 2018/8/14 11:21
 * Description:
 */
public class EnergySystem {

    private final double[] energyBoxes;
    private final Object lockObj = new Object();

    public EnergySystem(int n, double initialEnergy) {
        energyBoxes = new double[n];
        for(int i = 0;i < energyBoxes.length;i++) {
            energyBoxes[i] = initialEnergy;
        }
    }

    public void transfer(int from, int to, double amount) {

        synchronized(lockObj) {
//            if(energyBoxes[from] < amount)
//                return;
            /* 线程互斥操作:while循环,保证条件不满足时任务都会被条件阻挡
            *  而不是继续竞争CPU资源
            *  等待的线程在Wait set*/
            while(energyBoxes[from] < amount) {
                try {
                    lockObj.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.print(Thread.currentThread().getName());
            energyBoxes[from] -= amount;
            System.out.printf("从%d转移%10.2f单位能量到%d",from, amount,to);
            energyBoxes[to] += amount;
            System.out.printf("能量总和:%10.2f%n",getTotalEnergies());
            // 唤醒所有在lockObj对象上等待的线程
            lockObj.notifyAll();
        }

    }
    /*
    *  获得能量世界的能量总和*/
    public double getTotalEnergies() {
        double sum = 0;
        for(double amout: energyBoxes)
            sum += amout;
        return sum;
    }
    /* 返回能量盒子的长度*/
    public int getBoxAmount() {
        return energyBoxes.length;
    }
}
